package com.group3.service.impl;

import brave.Span;
import brave.Tracer;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.group3.dao.UserDao;
import com.group3.model.RegisterRequest;
import com.group3.model.User;
import com.group3.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private Tracer tracer;

    @Override
    @SentinelResource(
            value = "queryUserById",
            blockHandler = "handleBlock",
            fallback = "handleFallback"
    )
    public User queryUserById(Integer uid) {
        // 原有逻辑保持不变
        Span span = tracer.nextSpan().name("user:query").start();
        try (Tracer.SpanInScope scope = tracer.withSpanInScope(span)) {
            span.tag("method", "queryUserById");
            span.tag("uid", String.valueOf(uid));

            // 模拟uid=1的请求响应时间过长（超过1000ms）
            if (uid == 1) {
                try {
                    Thread.sleep(2000); // 2秒延迟，触发熔断
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }

            // 模拟uid=2的请求抛出异常（触发异常比例熔断）
            if (uid == 2) {
                throw new RuntimeException("数据库连接超时");
            }

            User user = userDao.selectById(uid);
            if (user == null) {
                span.tag("result", "not_found");
            } else {
                span.tag("result", "success");
            }
            return user;
        } catch (Exception e) {
            span.error(e);
            throw e;
        } finally {
            span.finish();
        }
    }

    @Override
    @Transactional
    @SentinelResource(
            value = "registerUser",
            blockHandler = "handleRegisterBlock",
            fallback = "handleRegisterFallback"
    )
    public User registerUser(RegisterRequest request) {
        // 原有逻辑保持不变
        Span span = tracer.nextSpan().name("user:register").start();
        try (Tracer.SpanInScope scope = tracer.withSpanInScope(span)) {
            span.tag("username", request.getUsername());
            span.tag("email", request.getEmail());

            // 1. 验证用户名是否已存在
            User existingUser = userDao.selectByUsername(request.getUsername());
            if (existingUser != null) {
                span.tag("error", "username-exists");
                throw new IllegalArgumentException("用户名已存在");
            }

            // 2. 创建用户对象
            User newUser = new User();
            newUser.setUsername(request.getUsername());
            newUser.setPassword(request.getPassword());
            newUser.setEmail(request.getEmail());
            newUser.setTelephone(request.getPhone());

            // 3. 插入数据库
            userDao.insert(newUser);

            span.tag("result", "success");
            span.tag("user.id", String.valueOf(newUser.getUid()));
            return newUser;
        } catch (Exception e) {
            span.error(e);
            span.tag("error.message", e.getMessage());
            throw e;
        } finally {
            span.finish();
        }
    }

    @Override
    @SentinelResource(
            value = "login",
            blockHandler = "handleLoginBlock",
            fallback = "handleLoginFallback"
    )
    public User login(String username, String password) {
        // 原有逻辑保持不变
        User user = userDao.selectByUsername(username);

        if (user == null) {
            throw new IllegalArgumentException("用户名不存在");
        }
        if (!password.equals(user.getPassword())) {
            throw new IllegalArgumentException("密码错误");
        }
        return user;
    }

    // 流控处理方法（QPS超过阈值时调用）
    public User handleBlock(Integer uid, BlockException ex) {
        System.err.println("流控触发: " + ex.getClass().getSimpleName());
        User fallbackUser = new User();
        fallbackUser.setUid(-1);
        fallbackUser.setUsername("系统繁忙，请稍后再试");
        return fallbackUser;
    }

    // 熔断降级处理方法（RT过长或异常比例过高时调用）
    public User handleFallback(Integer uid, Throwable ex) {
        System.err.println("熔断降级触发: " + ex.getMessage());
        User fallbackUser = new User();
        fallbackUser.setUid(-2);
        fallbackUser.setUsername("服务暂时不可用");
        return fallbackUser;
    }

    // 注册接口的流控处理
    public User handleRegisterBlock(RegisterRequest request, BlockException ex) {
        System.err.println("注册接口流控触发: " + ex.getClass().getSimpleName());
        User fallbackUser = new User();
        fallbackUser.setUid(-1);
        fallbackUser.setUsername("注册请求过多，请稍后再试");
        return fallbackUser;
    }

    // 注册接口的熔断降级处理
    public User handleRegisterFallback(RegisterRequest request, Throwable ex) {
        System.err.println("注册接口熔断降级触发: " + ex.getMessage());
        User fallbackUser = new User();
        fallbackUser.setUid(-2);
        fallbackUser.setUsername("注册服务暂时不可用");
        return fallbackUser;
    }

    // 登录接口的流控处理
    public User handleLoginBlock(String username, String password, BlockException ex) {
        System.err.println("登录接口流控触发: " + ex.getClass().getSimpleName());
        User fallbackUser = new User();
        fallbackUser.setUid(-1);
        fallbackUser.setUsername("登录请求过多，请稍后再试");
        return fallbackUser;
    }

    // 登录接口的熔断降级处理
    public User handleLoginFallback(String username, String password, Throwable ex) {
        System.err.println("登录接口熔断降级触发: " + ex.getMessage());
        User fallbackUser = new User();
        fallbackUser.setUid(-2);
        fallbackUser.setUsername("登录服务暂时不可用");
        return fallbackUser;
    }
}